﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BitworkStudios.Wizard.Forms
{
    public partial class WizardHost : Form, IWizardHost
    {
        private const string DefaultValidationMessage = "Current page is not valid. Please fill in required information";

        public string ValidationMessage { get; set; }
        public IWizardModel Model { get; set; }

        public void AddPage(int key, IWizardPageBase wizardPage)
        {
            wizardPage.Model = Model;
            _wizardPages.Add(key, wizardPage);
        }

        #region Properties

        private readonly WizardPageCollection _wizardPages;
        public bool ShowFirstButton
        {
            get { return btnFirst.Visible; }
            set { btnFirst.Visible = value; }
        }
        public bool ShowLastButton
        {
            get { return btnLast.Visible; }
            set { btnLast.Visible = value; }
        }

        private bool _navigationEnabled = true;
        public bool NavigationEnabled
        {
            get { return _navigationEnabled; }
            set
            {
                btnFirst.Enabled = value;
                btnPrevious.Enabled = value;
                btnNext.Enabled = value;
                btnLast.Enabled = value;
                _navigationEnabled = value;
            }
        }

        #endregion

        #region Delegates & Events

        public event WizardCompletedEventHandler WizardCompleted;

        #endregion

        #region Constructor & Window Event Handlers

        public WizardHost(IWizardModel wizardModel)
        {
            InitializeComponent();
            _wizardPages = new WizardPageCollection();
            _wizardPages.WizardPageLocationChanged += WizardPagesWizardPageLocationChanged;
            ValidationMessage = DefaultValidationMessage;
            Model = wizardModel;
        }

        public void WizardPagesWizardPageLocationChanged(WizardPageLocationChangedEventArgs e)
        {
            LoadNextPage(e.PageIndex, e.PreviousPageIndex, true);
        }

        #endregion

        #region Private Methods

        public void NotifyWizardCompleted()
        {
            if (WizardCompleted != null)
            {
                OnWizardCompleted();
                WizardCompleted();
            }
        }
        public void OnWizardCompleted()
        {
            _wizardPages.LastPage.Save();
            _wizardPages.Reset();
            DialogResult = DialogResult.OK;
        }

        public void UpdateNavigation()
        {
            #region Reset

            btnNext.Enabled = true;
            btnNext.Visible = true;

            btnLast.Text = "Last >>";
            btnLast.Enabled = ShowLastButton;

            #endregion

            bool canMoveNext = _wizardPages.CanMoveNext;
            bool canMovePrevious = _wizardPages.CanMovePrevious;

            btnPrevious.Enabled = canMovePrevious;
            btnFirst.Enabled = canMovePrevious;

            if (canMoveNext)
            {
                btnNext.Text = "Next >";
                btnNext.Enabled = true;

                if (ShowLastButton)
                {
                    btnLast.Enabled = true;
                }
            }
            else
            {
                if (ShowLastButton)
                {
                    btnLast.Text = "Finish";
                    btnNext.Visible = false;
                }
                else
                {
                    btnNext.Text = "Finish";
                    btnNext.Visible = true;
                }
            }
        }

        public bool CheckPageIsValid()
        {
            if (!_wizardPages.CurrentPage.PageValid)
            {
                MessageBox.Show(
                    string.Concat(ValidationMessage, Environment.NewLine, Environment.NewLine, _wizardPages.CurrentPage.ValidationMessage),
                    "Details Required",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Exclamation);
                return false;
            }
            return true;
        }

        #endregion

        #region Public Methods

        public void LoadWizard()
        {
            _wizardPages.MovePageFirst();
        }
        public void LoadNextPage(int pageIndex, int previousPageIndex, bool savePreviousPage)
        {
            if (pageIndex != -1)
            {
                contentPanel.Controls.Clear();
                contentPanel.Controls.Add(((IWizardPage)_wizardPages[pageIndex]).Content);
                if (savePreviousPage && previousPageIndex != -1)
                {
                    _wizardPages[previousPageIndex].Save();
                }
                _wizardPages[pageIndex].Load();
                UpdateNavigation();
            }
        }

        #endregion

        #region Event Handlers

        public void ButtonFirstClick(object sender, EventArgs e)
        {
            //if (!CheckPageIsValid()) //Maybe doesn't matter if move back; only matters if move forward
            //{ return; }

            _wizardPages.MovePageFirst();
        }

        public void ButtonPreviousClick(object sender, EventArgs e)
        {
            //if (!CheckPageIsValid()) //Maybe doesn't matter if move back; only matters if move forward
            //{ return; }

            _wizardPages.MovePagePrevious();
        }

        public void ButtonNextClick(object sender, EventArgs e)
        {
            if (!CheckPageIsValid())
            { return; }

            if (_wizardPages.CanMoveNext)
            {
                _wizardPages.MovePageNext();
            }
            else
            {
                //This is the finish button and it has been clicked
                NotifyWizardCompleted();
            }
        }

        public void ButtonLastClick(object sender, EventArgs e)
        {
            if (!CheckPageIsValid())
            { return; }

            if (_wizardPages.CanMoveNext)
            {
                _wizardPages.MovePageLast();
            }
            else
            {
                //This is the finish button and it has been clicked
                NotifyWizardCompleted();
            }
        }

        #endregion
    }
}
